<template>
  <div class="screen-shot" id="screen-shot">
    <align-line></align-line>
    <ruler :isShowReferLine="referLine.enable" :lang="rulerOption.lang" :thick="rulerOption.thick"
      :scale="rulerOption.scale" :width="rulerOption.width" :height="rulerOption.height" :startX="rulerOption.startX"
      :startY="rulerOption.startY" :horLineArr="rulerOption.lines.h" :verLineArr="rulerOption.lines.v"
      :cornerActive="rulerOption.cornerActive" :palette="rulerOption.palette" @onCornerClick="handleRuleCornerClick"
      @handleLine="handleLine"></ruler>
    <div id="screens" @wheel="handleScreenWheel" @scroll="handleScreenScroll" :style="screenShotStyle">
      <div :style="canvasStyle" id="screen-container">
        <div id="comps-map" :style="canvasMapStyle">
          <div class="canvas-map-layout-item" v-for="items in components" :key="items.id"
            :style="canvasMapLayoutItem(items)"></div>
        </div>
        <div id="canvas-comps" tabindex="0" :onkeydown="handleKeyDown" class="canvas-panel" :style="canvasCompsStyle"
          @drop="handleCompDrop" @dragover="handleCompDragOver" @click="handleSelectCurComponent">
          <main-editor></main-editor>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {
  computed,
  defineComponent,
  nextTick,
  onMounted,
  ref,
  watch,
} from "vue";
import AlignLine from "./align-line.vue";
import Ruler from "./ruler/ruler.vue";
import { useStore } from "vuex";
import MainEditor from "./main-editor/main-editor.vue";
import { createComponent } from "../../../../components/lib";
import { ElMessageBox } from "element-plus";

export default defineComponent({
  name: "canvas-main",
  components: { MainEditor, Ruler, AlignLine },
  setup() {
    const store = useStore();
    const deleteCompFlag = ref(false);
    const components = computed(() => store.state.design.components);
    const pageConfig = computed(() => store.state.design.pageConfig);
    const canvas = computed(() => store.state.design.canvas);
    const scale = computed(() => canvas.value.scale);
    watch(
      () => scale.value,
      (val) => {
        rulerOption.value.scale = val;
        nextTick(() => {
          handleScreenScroll();
        });
      }
    );
    const referLine = computed(() => store.state.design.referLine);
    const rulerOption = ref({
      // bgColor: "#0e1013",
      lang: "zh-CN",
      scale: 0.8, //658813476562495, //1,
      thick: 22, // thick size 辅助尺 大小
      width: 1920,
      height: 860,
      startX: 0, // x at the beginning of the ruler
      startY: 0,
      shadow: {
        x: 0,
        y: 0,
        width: 0,
        height: 0,
      }, // 阴影标尺上的大小和起始坐标
      lines: {
        // 默认显示辅助线位置
        h: [0],
        v: [0],
      },
      cornerActive: true,
      palette: {
        bgColor: "#0e1013",
        longFgColor: "#494f53",
        shortFgColor: "#494f53",
        fontColor: "#bcc9d4",
        shadowColor: "transparent",
        lineColor: "#2196f3",
        borderColor: "rgba(161,174,179,.6)",
        cornerActiveColor: "#fff",
      },
    });
    const selectedComp = computed(() => store.getters["design/selectedComp"]);
    const copyComponentId = computed(() => {
      if (selectedComp.value) {
        return selectedComp.value.id;
      }
    });
    const screenShotStyle = computed(() => {
      return {
        width: `100%`,
        height: `100%`,
      };
    });
    const canvasStyle = computed(() => {
      return {
        position: "absolute",
        top: 60 + "px",
        left: 60 + "px",
        width: `${(pageConfig.value.width + 200) * scale.value}px`,
        height: `${(pageConfig.value.height + 200) * scale.value}px`,
      };
    });
    const canvasMapStyle = computed(() => {
      return {
        position: "absolute",
        width: `${pageConfig.value.width * scale.value}px`,
        height: `${pageConfig.value.height * scale.value}px`,
      };
    });
    const canvasCompsStyle = computed(() => {
      return {
        width: `${pageConfig.value.width}px`,
        height: `${pageConfig.value.height}px`,
        transform: `scale(${scale.value}) translate(0px, 0px)`,
        backgroundImage: `url(${pageConfig.value.bgImage})`,
        backgroundColor: pageConfig.value.bgColor,
      };
    });
    const canvasMapLayoutItem = (com) => {
      return {
        position: "absolute",
        width: `${com.attr.w * scale.value}px`,
        height: `${com.attr.h * scale.value}px`,
        top: "0px",
        left: "0px",
        transform: `translate(${com.attr.x * scale.value}px, ${
          com.attr.y * scale.value
        }px)`,
      };
    };
    const handleRuleCornerClick = () => {
      rulerOption.value.isShowReferLine = !rulerOption.value.isShowReferLine;
      rulerOption.value.cornerActive = !rulerOption.value.cornerActive;
    };
    const handleLine = (lines) => {
      rulerOption.value.lines = lines;
    };
    const handleScreenWheel = (e) => {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault();
        const nextScale = parseFloat(
          Math.max(0.2, scale.value - e.deltaY / 500).toFixed(2)
        );
        scale.value = nextScale;
      }
      nextTick(() => {
        handleScreenScroll();
      });
    };
    const handleScreenScroll = () => {
      const screensRect = document
        .querySelector("#screens")
        .getBoundingClientRect();
      const canvasRect = document
        .querySelector("#canvas-comps")
        .getBoundingClientRect();
      // // 标尺开始的刻度
      const startX =
        (screensRect.left + rulerOption.value.thick - canvasRect.left) /
        scale.value;
      const startY =
        (screensRect.top + rulerOption.value.thick - canvasRect.top) /
        scale.value;
      rulerOption.value.startX = startX >> 0;
      rulerOption.value.startY = startY >> 0;
    };
    const handleCompDrop = async (e) => {
      try {
        e.preventDefault();
        e.stopPropagation();
        const comName = e.dataTransfer.getData("text");
        if (!comName) return;
        const com = createComponent(comName);
        com.attr.y = e.offsetY;
        com.attr.x = e.offsetX;
        await store.dispatch("design/addCom", com);
        store.commit("design/selectComp", com.id);
        // if (com.apis.source) {
        //   await com.loadData();
        //   // todo 数据加载
        // }
      } catch {}
    };
    const handleCompDragOver = (e) => {
      e.preventDefault();
      e.stopPropagation();
      // e.dataTransfer.dropEffect = "copy";
    };
    const handleSelectCurComponent = () => {
      store.commit("design/selectComp", "");
    };
    const handleCompDel = () => {
      if (selectedComp.value) {
        deleteCompFlag.value = true;
        ElMessageBox.confirm(`你确定删除当前组件？`, "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            store.commit("design/DELETE_COMP", selectedComp.value);
            deleteCompFlag.value = false;
          })
          .catch(() => {
            deleteCompFlag.value = false;
          });
      }
    };
    const handleKeyDown = (e) => {
      if (e.key === "Delete" || e.key === "Backspace") {
        handleCompDel();
      }
      const ctrl = navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey;
      const cKey = ["c", "C"].includes(e.key);
      const vKey = ["v", "V"].includes(e.key);
      if (ctrl && cKey) {
        if (selectedComp.value) {
          copyComponentId.value = selectedComp.value.id;
        }
      } else if (ctrl && vKey) {
        if (copyComponentId.value) {
          store.commit("design/COPY_COMP", copyComponentId.value);
        }
      }
    };
    onMounted(() => {
      rulerOption.value.scale = scale.value;
      nextTick(() => {
        handleScreenScroll();
      });
    });
    return {
      copyComponentId,
      rulerOption,
      pageConfig,
      canvas,
      components,
      canvasMapStyle,
      canvasCompsStyle,
      screenShotStyle,
      canvasStyle,
      deleteCompFlag,
      handleCompDel,
      handleLine,
      canvasMapLayoutItem,
      handleRuleCornerClick,
      handleScreenScroll,
      handleScreenWheel,
      handleCompDrop,
      handleCompDragOver,
      handleSelectCurComponent,
      handleKeyDown,
      referLine,
    };
  },
});
</script>

<style lang="less" scoped>
#screen-shot {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  position: relative;

  #screens {
    position: relative;
    overflow: auto;
    height: 100%;
    width: 100%;
  }
}

#canvas-comps:focus-visible {
  border: 0;
  outline: 0;
}

.canvas-panel {
  top: 60px;
  left: 60px;
  background-position: center, right bottom;
  background-repeat: no-repeat, no-repeat;
  background-size: cover, contain;
  box-shadow: rgba(0, 0, 0, 0.5) 0 0 30px 0;
  transition: 0.2s all ease-in-out;
  transform-origin: 0 0;
}
</style>
